home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / hgraphic.zip / GRAPHICS.C < prev    next >
Text File  |  1988-04-12  |  20KB  |  637 lines

  1. /*****************************************************************************/
  2. /*    Hercules Compatible graphics routines written for Microsoft Quick C  */
  3. /*    version 1.0.  Compile with large model (option /AL).             */
  4. /*                                         */
  5. /*    Written by:    Ben Bederson   (c) 1988                     */
  6. /*               bbb7889@acf5.NYU.EDU                     */
  7. /*                                         */
  8. /*               222 East 19th St.  #3H                     */
  9. /*               New York, NY  10003                     */
  10. /*               (212) 260-2667                         */
  11. /*                                         */
  12. /*    These routines were written by myself for my own purposes and I make */
  13. /*    no guarantees, warentees, expressed, or implied, etc.  However,      */
  14. /*    I hope they are useful.  Everybody is free and encouraged to copy    */
  15. /*    and use these routines under the condition that this statement is    */
  16. /*    kept at the top without modification.  I would appreciate any         */
  17. /*    comments or criticisms or improvement/ideas about these routines.    */
  18. /*                                         */
  19. /*    Good luck.                                 */
  20. /*****************************************************************************/
  21.  
  22. #include <stdio.h>
  23. #include <conio.h>
  24. #include <malloc.h>
  25. #include <dos.h>
  26. #include "graphics.h"
  27.  
  28. /*****************************************************************************/
  29. /*                                         */
  30. /*         Routines in this file:                         */
  31. /*                                         */
  32. /*         graphics() - Enter monochrome 720x348 graphics mode (clear scn) */
  33. /*         text()    - Enter text mode                     */
  34. /*         cls()    - Clear the text screen                  */
  35. /*         grcls()    - Clear the graphics screen                 */
  36. /*         fill_screen()    - Fill the graphics screen to white         */
  37. /*         dot(x,y,color)    - Put a dot of color WHITE,BLACK, or XOR     */
  38. /*                  at the location x,y on the graphics screen */
  39. /*         line(x1,y1,x2,y2,color)                         */
  40. /*                - Draw a line from x1,y1 to x2,y2 in color   */
  41. /*         draw(shape,x,y,color)                         */
  42. /*                - Draw the shape as specified by a         */
  43. /*                  shape_type structure in the specified      */
  44. /*                  color at the specified location x,y.         */
  45. /*                  Not too fast.  Try draw_block for some     */
  46. /*                  really fast drawing.                 */
  47. /*         draw_block(shape,x,y,color)                     */
  48. /*                - Draw the shape as specified by a         */
  49. /*                  shape_type structure in the specified      */
  50. /*                  color at the specified location x,y.         */
  51. /*                  The location must be a byte boundary         */
  52. /*                  as this routine does not shift pixels.     */
  53. /*                  But, it is very fast!!!  It will not         */
  54. /*                  give an error if x,y is not a byte         */
  55. /*                  boundary, but will shift the block to      */
  56. /*                  draw it on a byte boundary.  (This only    */
  57. /*                  applies to the x-axis.             */
  58. /*         shift_up(shape,x,y,shift_num)                     */
  59. /*         shift_down(shape,x,y,shift_num)                     */
  60. /*         shift_left(shape,x,y,shift_num)                     */
  61. /*         shift_right(shape,x,y,shift_num)                     */
  62. /*                - Shifts the specified shape at the         */
  63. /*                  specified location by shift_num pixels     */
  64. /*                  in the direction corresponding to the      */
  65. /*                  routine name.  Really, just a rectangle    */
  66. /*                  is shifted specified by the size in the    */
  67. /*                  shape.  This is relatively slow because    */
  68. /*                  bits have to be shifted from one byte to   */
  69. /*                  the next.                     */
  70. /*                                         */
  71. /*            Note: Currently, only shift_right is implemented.    */
  72. /*                  Either use the block shifts, or it should be   */
  73. /*                  very easy to write shift_up,down, and left as  */
  74. /*                  they are just mirror images of shift_right.    */
  75. /*         shift_up_block(shape,x,y)                         */
  76. /*         shift_down_block(shape,x,y)                     */
  77. /*         shift_left_block(shape,x,y)                     */
  78. /*         shift_right_block(shape,x,y)                     */
  79. /*                - Shifts the specified shape at the         */
  80. /*                  specified location by 8 pixels in the      */
  81. /*                  direction corresponding to the routine     */
  82. /*                  name.  Really, just a rectangle is shifted */
  83. /*                  specified by the size in the shape.  This  */
  84. /*                  is very fast as entire bytes are moved     */
  85. /*                  without worrying about shifting bits.      */
  86. /*                Note: The shape must start on a byte         */
  87. /*                  boundary, or extra pixels will be moved    */
  88. /*                  with it.                     */
  89. /*                                         */
  90. /*****************************************************************************/
  91.  
  92. /*****************************************************************************/
  93. /*                                         */
  94. /*         User Info:                              */
  95. /*         ----------                              */
  96. /*                                         */
  97. /*         struct shape_type                             */
  98. /*                                         */
  99. /*         This structure represents a general shape.  x and y contain     */
  100. /*         the size in bytes of a shape.  shape_array is a pointer to      */
  101. /*         an array that must be allocated by the user.  The array is      */
  102. /*         a two dimensional array of single-byte characters where each    */
  103. /*         bit describes the shape: 1 ON, and 0 OFF.                 */
  104. /*                                         */
  105. /*         The colors are:                             */
  106. /*           WHITE    - Draw with pixels on.                     */
  107. /*           BLACK    - Draw with pixels off.                  */
  108. /*           XOR    - Draw with pixels opposite state of what they were  */
  109. /*           OVERWRITE - For drawing shapes, 1's put a pixel on, and       */
  110. /*               0's put a pixel off.  For other colors, 0's       */
  111. /*               don't do anything.                                */
  112. /*                                         */
  113. /*****************************************************************************/
  114.  
  115. char far* screen = (char far *)0xb0000000;
  116. int gr6845[] = {0x38, 0x2d, 0x30, 0x08, 0x5a, 0x00, 0x57, 0x57, 0x02,
  117.         0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  118. int te6845[] = {0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19, 0x02,
  119.         0x0d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  120.  
  121. /*****************************************************************************/
  122. /*                                         */
  123. /*    I enter graphics mode by directly accessing the 6845 graphics         */
  124. /*    controller chip.  I found the register addresses and data by         */
  125. /*    debugging a sample graphics program that came with my Everex         */
  126. /*    Hercules compatible graphics card.  I have tried them on both         */
  127. /*    Leading Edge and Five Star computers with Hercules-compatible         */
  128. /*    graphics cards with 100% success, so I expect that it should         */
  129. /*    work.                                     */
  130. /*                                         */
  131. /*****************************************************************************/
  132.  
  133. graphics()
  134. {
  135.   int i;
  136.  
  137.   outp(0x3b8,0);
  138.   outp(0x3bf,3);
  139.   for (i=0; i<18; i++) {
  140.     outp(0x3b4,i);
  141.     outp(0x3b5,gr6845[i]);
  142.   }
  143.   outp(0x3b8,6);
  144.   grcls();
  145.   outp(0x3b8,14);
  146. }
  147.  
  148. /*****************************************************************************/
  149. /*                                         */
  150. /*    Read the comment before about the graphics() routine to find         */
  151. /*    about this routine.                             */
  152. /*                                         */
  153. /*****************************************************************************/
  154.  
  155. text()
  156. {
  157.   int i;
  158.   union REGS regs;
  159.  
  160.   regs.x.ax = 2;
  161.   int86(0x10, ®s, ®s);
  162.   outp(0x3bf,0);
  163.   outp(0x3b8,0x28);
  164.   for (i=0; i<18; i++) {
  165.     outp(0x3b4,i);
  166.     outp(0x3b5,te6845[i]);
  167.   }
  168.   cls();
  169. }
  170.  
  171. /*****************************************************************************/
  172. /*                                         */
  173. /*    The graphics memory starts at B000:0000, and very unfortunately      */
  174. /*    is not mapped as you might expect.  Each row is simple.  A byte      */
  175. /*    controls 8 pixels, one bit per pixel, high-order bit controlling     */
  176. /*    the left-most pixel.  This continues sequentially accross the         */
  177. /*    row.  To find the address of the next row, however, is not so         */
  178. /*    easy.  By plotting many points, I finally came upon the algorithm    */
  179. /*    in the macro byte_addr(x,y) in the graphics.h file.  Essentially,    */
  180. /*    you add 0x2000 to get the next row unless you are greater than         */
  181. /*    0x8000 in which case you subtract 0x8000 and add 0x5a.    If         */
  182. /*    anybody understands why the screen was memory mapped in this         */
  183. /*    crazy way, please tell me.  I am